package com.th.supcom.pds.phamapply.client.page;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.carefx.framework.container.client.context.AppContext;
import net.carefx.framework.container.client.page.IPageEntryPoint;
import net.carefx.framework.container.client.page.PageContext;
import net.carefx.framework.reflection.shared.annotations.Reflectable;

import com.extjs.gxt.ui.client.Style.HideMode;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.Style.LayoutRegion;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.GridEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.util.Margins;
import com.extjs.gxt.ui.client.widget.Info;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.TabItem;
import com.extjs.gxt.ui.client.widget.TabPanel;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.layout.BorderLayout;
import com.extjs.gxt.ui.client.widget.layout.BorderLayoutData;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.th.supcom.pds.common.client.model.CodeConstants;
import com.th.supcom.pds.common.enums.AvailableEnum;
import com.th.supcom.pds.common.enums.StockEnoughEnum;
import com.th.supcom.pds.common.utils.ClientColorDescUtils;
import com.th.supcom.pds.common.utils.ClientUtils;
import com.th.supcom.pds.phamapply.client.model.InpPhamApplyDetailModel;
import com.th.supcom.pds.phamapply.client.model.InpPhamApplyDetailSummaryModel;
import com.th.supcom.pds.phamapply.client.model.InpPhamDispenseDetailModel;
import com.th.supcom.pds.phamapply.client.service.InpPhamApplyDetailRpc;
import com.th.supcom.pds.phamapply.client.service.InpPhamApplyDetailRpcAsync;
import com.th.supcom.pds.phamapply.client.service.InpPhamDispenseDetailRpc;
import com.th.supcom.pds.phamapply.client.service.InpPhamDispenseDetailRpcAsync;
import com.th.supcom.pds.phamapply.client.widget.phamapplydetail.PhamApplyCancelConditionForm;
import com.th.supcom.pds.phamapply.client.widget.phamapplydetail.PhamApplyCancelConditionMain;
import com.th.supcom.pds.phamapply.client.widget.phamdispense.PhamDispenseCollectGrid;
import com.th.supcom.pds.phamapply.client.widget.phamdispense.PhamDispenseCurrentApplyGrid;
import com.th.supcom.pds.phamapply.client.widget.phamdispense.PhamDispenseDetailGrid;
import com.th.supcom.pds.phamapply.client.widget.phamdispense.PhamDispenseNurseUnitInfoGrid;
import com.th.supcom.pds.phamapply.client.widget.phamdispense.PhamDispenseOffsetAdjustMainGrid;
import com.th.supcom.pds.phamapply.client.widget.phamdispense.PhamDispenseOffsetGrid;

/**
 * 住院撤销查询入口类实现.
 * 
 */
@Reflectable
public class InpPhamApplyCancelEntryPoint implements IPageEntryPoint
{
    private PhamApplyCancelConditionMain m_phamApplyCancelConditionMain;
    private Button m_cancleBtn;
    private Button m_clearBtn;
    private PhamApplyCancelConditionForm m_phamApplyCancelConditionForm;
    private PhamDispenseNurseUnitInfoGrid m_phamDispenseNurseUnitInfoGrid;
    private PhamDispenseCollectGrid m_phamDisenpseCollectGrid;
    private PhamDispenseOffsetAdjustMainGrid m_offsetAdjustMainGrid;
    private PhamDispenseDetailGrid m_phamDispenseDetailGrid;
    private PhamDispenseCurrentApplyGrid m_currentApplyGrid;
    private PhamDispenseOffsetGrid m_offsetGrid;
    private static InpPhamDispenseDetailRpcAsync s_dipenseDetailRpc = GWT.create (InpPhamDispenseDetailRpc.class);
    private static InpPhamApplyDetailRpcAsync s_applyDetailRpc = GWT.create (InpPhamApplyDetailRpc.class);

    @Override
    public void start (PageContext context)
    {
        initUI (context);
        addEventListeners ();
    }

    private void initData ()
    {  //验证查询条件
        if(!veryParams ()){
            return;
        };
        InpPhamApplyDetailModel model =new InpPhamApplyDetailModel();
        model.setNurseUnit (ClientUtils.getOrgModel().getOrgCode()); 
        model.setBeginDateOfDay (m_phamApplyCancelConditionForm.getBeginDate ().getValue ());
        model.setEndDateOfDay (m_phamApplyCancelConditionForm.getEndDate ().getValue ());
        s_dipenseDetailRpc.getInpPhamCancelNurseUnit (model,
                                                      new AsyncCallback <List <InpPhamApplyDetailModel>> ()
                                                      {

                                                          @Override
                                                          public void onSuccess (List <InpPhamApplyDetailModel> result)
                                                          {
                                                              m_phamDispenseNurseUnitInfoGrid.getStore ().removeAll ();
                                                              m_phamDispenseNurseUnitInfoGrid.getStore ().add (result);
                                                          }

                                                          @Override
                                                          public void onFailure (Throwable caught)
                                                          {
                                                              MessageBox.alert (CodeConstants.PROMPT,
                                                                                caught.getLocalizedMessage (), null);
                                                          }
                                                      });

    }

    private void initUI (PageContext context)
    {
        context.getWorkBench ().getBodyView ().getWorkspace ().getContextView ().asLayoutContainer ().hide ();

        LayoutContainer mainLayoutContainer;
        mainLayoutContainer = context.getContainer ();
        mainLayoutContainer.setLayout (new BorderLayout ());
        mainLayoutContainer.setHideMode (HideMode.OFFSETS);

        createButton ();
        creatGrid ();
        TabPanel tabPanel = createTabPanel ();
        BorderLayoutData centerData = new BorderLayoutData (LayoutRegion.CENTER);
        centerData.setMargins (new Margins (2, 0, 2, 0));
        BorderLayoutData southData = new BorderLayoutData (LayoutRegion.SOUTH, 30);
        southData.setMargins (new Margins (2, 5, 2, 0));
        BorderLayoutData westData = new BorderLayoutData (LayoutRegion.WEST, 200);
        westData.setMargins (new Margins (2, 5, 2, 0));

        mainLayoutContainer.add (tabPanel, centerData);
        mainLayoutContainer.add (m_phamApplyCancelConditionMain, westData);
        mainLayoutContainer.add (ClientColorDescUtils.createPhamDispenseColorDesc (), southData);
    }

    private void createButton ()
    {
        m_cancleBtn = new Button ("撤销");
        m_clearBtn = new Button ("清屏");
    }

    private TabPanel createTabPanel ()
    {
        TabPanel tabPanel = new TabPanel ();
        tabPanel.setLayoutData (new FitLayout ());

        TabItem detailItem = new TabItem ("请领明细");
        detailItem.add (m_phamDispenseDetailGrid);
        detailItem.setLayout (new FitLayout ());
        TabItem collectItem = new TabItem ("请领汇总");
        collectItem.add (m_phamDisenpseCollectGrid);
        collectItem.setLayout (new FitLayout ());
        TabItem offsetItem = new TabItem ("冲抵调整");
        offsetItem.add (m_offsetAdjustMainGrid);
        offsetItem.setLayout (new FitLayout ());

        tabPanel.add (detailItem);
        tabPanel.add (collectItem);
        tabPanel.add (offsetItem);
        return tabPanel;
    }

    private void creatGrid ()
    {
        m_phamApplyCancelConditionMain=new PhamApplyCancelConditionMain();
        m_phamDispenseNurseUnitInfoGrid = new PhamDispenseNurseUnitInfoGrid ();
        m_phamApplyCancelConditionForm=new PhamApplyCancelConditionForm();
        m_phamApplyCancelConditionMain.setPhamDispenseNurseUnitInfoGrid (m_phamDispenseNurseUnitInfoGrid);
        m_phamApplyCancelConditionMain.setPhamApplyCancelConditionForm (m_phamApplyCancelConditionForm);
        m_phamApplyCancelConditionMain.initUI ();
        m_phamDispenseDetailGrid = new PhamDispenseDetailGrid ();
        m_phamDispenseDetailGrid.setButtonAlign (HorizontalAlignment.CENTER);
        m_phamDispenseDetailGrid.addButton (m_cancleBtn);
        m_phamDispenseDetailGrid.addButton (m_clearBtn);
        m_phamDisenpseCollectGrid = new PhamDispenseCollectGrid ();
        m_currentApplyGrid = new PhamDispenseCurrentApplyGrid ();
        m_offsetGrid = new PhamDispenseOffsetGrid ();
        m_offsetAdjustMainGrid = new PhamDispenseOffsetAdjustMainGrid ();
        m_offsetAdjustMainGrid.setPhamDispenseOffsetGrid (m_offsetGrid);
        m_offsetAdjustMainGrid.setPhamDispenseCurrentApplyGrid (m_currentApplyGrid);
        m_offsetAdjustMainGrid.initUI ();
    }

    /**
     * 添加组事件
     */
    private void addEventListeners ()
    {
        m_phamDispenseNurseUnitInfoGrid.getGrid ()
                                       .addListener (Events.CellClick,
                                                     new Listener <GridEvent <InpPhamDispenseDetailModel>> ()
                                                     {

                                                         @Override
                                                         public void handleEvent (GridEvent <InpPhamDispenseDetailModel> be)
                                                         {
                                                             loadData ();
                                                         }
                                                     });
        /** 撤销 */
        m_cancleBtn.addSelectionListener (new SelectionListener <ButtonEvent> ()
        {

            @Override
            public void componentSelected (final ButtonEvent ce)
            {
                cancleData ();

            }
        });
        m_clearBtn.addSelectionListener (new SelectionListener <ButtonEvent> ()
        {
            @Override
            public void componentSelected (final ButtonEvent ce)
            {
                clearData ();
            }
        });
        m_phamApplyCancelConditionForm.getQueryBtn ().addSelectionListener (new SelectionListener <ButtonEvent> ()
        {
            @Override
            public void componentSelected (final ButtonEvent ce)
            {
                 initData ();
            }
        });

    }

    @Override
    public void stop (PageContext context)
    {
        return;
    }

    public void loadData ()
    {
        InpPhamApplyDetailModel model = m_phamDispenseNurseUnitInfoGrid.getGrid ().getSelectionModel ()
                                                                       .getSelectedItem ();
        if (model == null)
        {
            clearData ();
            return;
        }
        if("1".equals (model.getDisp ())){
            m_cancleBtn.setEnabled (true);
        }else{
            m_cancleBtn.setEnabled (false); 
        }
        m_phamDispenseDetailGrid.getGrid ().mask ("正在拼命加载");
        s_dipenseDetailRpc.getApplyDetailByApplyNoAndDispensary (model.getApplyNo (), null,
                                                                 new AsyncCallback <List <InpPhamApplyDetailModel>> ()
                                                                 {

                                                                     @Override
                                                                     public void onFailure (Throwable caught)
                                                                     {
                                                                         m_phamDispenseDetailGrid.getGrid ().unmask ();
                                                                         MessageBox.alert (CodeConstants.PROMPT,
                                                                                           caught.getLocalizedMessage (),
                                                                                           null);
                                                                     }

                                                                     @Override
                                                                     public void onSuccess (List <InpPhamApplyDetailModel> result)
                                                                     {
                                                                         m_phamDispenseDetailGrid.getStore ()
                                                                                                 .removeAll ();
                                                                         m_phamDispenseDetailGrid.getStore ()
                                                                                                 .add (result);
                                                                         getPhamApplySummary ();
                                                                         m_phamDispenseDetailGrid.getGrid ().unmask ();
                                                                     }
                                                                 });
    }

    private void clearData ()
    {
        m_phamDispenseDetailGrid.clear ();
        ;
        m_phamDisenpseCollectGrid.clear ();
    }

    /**
     * 获取药品请领汇总
     */
    public void getPhamApplySummary ()
    {
        List <InpPhamApplyDetailModel> models = m_phamDispenseDetailGrid.getGrid ().getStore ().getModels ();
        List <InpPhamApplyDetailSummaryModel> summaryModels = new ArrayList <InpPhamApplyDetailSummaryModel> ();
        // 按照药品进行分组，计算每个药品的汇总
        Map <String, List <InpPhamApplyDetailModel>> phamMap = convertToMapByPhamCode (models);
        for (Map.Entry <String, List <InpPhamApplyDetailModel>> phamEntry : phamMap.entrySet ())
        {
            if (phamEntry.getValue ().isEmpty ())
            {
                continue;
            }

            InpPhamApplyDetailModel model = phamEntry.getValue ().get (0);
            // 如果药品库存不足或者不可供直接过滤掉
            if (StockEnoughEnum.NO.getEnumCode ().equals (model.getStockEnoughFlag ())
                || AvailableEnum.NO.getEnumCode ().equals (model.getApplySupplyFlag ()))
            {
                continue;
            }
            summaryModels.add (statPham (phamEntry.getValue ()));
        }
        m_phamDisenpseCollectGrid.getGrid ().getStore ().removeAll ();
        m_phamDisenpseCollectGrid.getGrid ().getStore ().add (summaryModels);
        getOffsetPhamSummary ();
    }

    /**
     * 根据药品标准码将list转换成Map
     * 
     * @return
     */
    private Map <String, List <InpPhamApplyDetailModel>> convertToMapByPhamCode (List <InpPhamApplyDetailModel> models)
    {
        Map <String, List <InpPhamApplyDetailModel>> map = new HashMap <String, List <InpPhamApplyDetailModel>> ();
        for (InpPhamApplyDetailModel inpPhamApplyDetailModel : models)
        {
            List <InpPhamApplyDetailModel> temp = null;

            if (map.containsKey (inpPhamApplyDetailModel.getPhamStdCode ()))
            {
                temp = map.get (inpPhamApplyDetailModel.getPhamStdCode ());
            }
            else
            {
                temp = new ArrayList <InpPhamApplyDetailModel> ();
            }
            temp.add (inpPhamApplyDetailModel);
            map.put (inpPhamApplyDetailModel.getPhamStdCode (), temp);
        }
        return map;
    }

    /**
     * 药品统计
     */
    private InpPhamApplyDetailSummaryModel statPham (List <InpPhamApplyDetailModel> list)
    {
        InpPhamApplyDetailSummaryModel summaryModel = new InpPhamApplyDetailSummaryModel ();

        int applyCountSum = 0;
        double costSum = 0.0;
        if (list.isEmpty ())
        {
            return summaryModel;
        }

        for (InpPhamApplyDetailModel model : list)
        {
            if (null == model.getApplyAmount () || null == model.getCosts ())
            {
                continue;
            }

            applyCountSum += model.getApplyAmount ();
            costSum += model.getCosts ();
        }

        InpPhamApplyDetailModel detailModel = list.get (0);
        if (AvailableEnum.NO.getEnumCode ().equals (detailModel.getDispenseResultFlag ()))
        {
            return summaryModel;
        }

        summaryModel.setDetailSumAmount (applyCountSum);
        summaryModel.setPhamStdCode (detailModel.getPhamStdCode ());
        summaryModel.setDispensary (detailModel.getApplyDispensary ());
        summaryModel.setDispensaryName (detailModel.getApplyDispensaryName ());
        summaryModel.setApplySupplyFlag (detailModel.getApplySupplyFlag ());
        summaryModel.setStockEnoughFlag (detailModel.getStockEnoughFlag ());
        summaryModel.setPhamName (detailModel.getPhamName ());
        summaryModel.setPhamSpec (detailModel.getPhamSpec ());
        summaryModel.setTotalCost (costSum);
        summaryModel.setDosageUnit (detailModel.getApplyUnitName ());
        getDetailInfo (list, summaryModel);
        return summaryModel;
    }

    /**
     * 获取明细信息
     * 
     * @param list
     * @param summaryModel
     */
    private void getDetailInfo (List <InpPhamApplyDetailModel> list, InpPhamApplyDetailSummaryModel summaryModel)
    {
        // 记录每个药品,每个人的药品申请数量、实际摆药数量、冲抵数量
        Map <Long, Map <String, Integer>> countMap = new HashMap <Long, Map <String, Integer>> ();
        // 记录每个人的患者信息
        Map <Long, InpPhamApplyDetailModel> patInfoMap = new HashMap <Long, InpPhamApplyDetailModel> ();
        for (InpPhamApplyDetailModel model : list)
        {
            // 申请数量
            Integer applyCount = 0;
            // 实际摆药数量
            Integer actualCount = 0;
            // 冲抵数量
            Integer offsetCount = 0;
            // 记录单个药品的申请数量、实际摆药数量、冲抵数量
            Map <String, Integer> map = null;

            if (countMap.containsKey (model.getPaiVisitId ()))
            {
                map = countMap.get (model.getPaiVisitId ());
            }
            else
            {
                map = new HashMap <String, Integer> ();
            }

            if (map.containsKey ("applyCount"))
            {
                applyCount = map.get ("applyCount");
            }

            if (map.containsKey ("actualCount"))
            {
                actualCount = map.get ("actualCount");
            }

            if (map.containsKey ("offsetCount"))
            {
                offsetCount = map.get ("offsetCount");
            }

            applyCount += model.getApplyAmount ();

            if (null != model.getActualCount ())
            {
                actualCount += model.getActualCount ();
            }
            if (null != model.getActualOffsetAmount ())
            {
                offsetCount += model.getActualOffsetAmount ();
            }
            map.put ("applyCount", applyCount);
            map.put ("actualCount", actualCount);
            map.put ("offsetCount", offsetCount);
            countMap.put (model.getPaiVisitId (), map);
            patInfoMap.put (model.getPaiVisitId (), model);
        }
        // 摆药明细
        String dispenseInstr = "";
        // 冲抵明细
        String offsetInStr = "";
        // 实际摆药总量
        int actualDispeseCount = 0;
        for (Map.Entry <Long, Map <String, Integer>> entry : countMap.entrySet ())
        {
            dispenseInstr += patInfoMap.get (entry.getKey ()).getBedNo () + "&"
                             + countMap.get (entry.getKey ()).get ("applyCount") + " ";
            offsetInStr += patInfoMap.get (entry.getKey ()).getBedNo () + "&"
                           + countMap.get (entry.getKey ()).get ("offsetCount") + " ";
            actualDispeseCount += countMap.get (entry.getKey ()).get ("actualCount");
        }

        summaryModel.set ("dispenseInstr", dispenseInstr);
        summaryModel.set ("offsetInStr", offsetInStr);
        summaryModel.set ("actualDispeseCount", actualDispeseCount);
    }

    /**
     * 获取可冲抵的药品信息
     */
    public void getOffsetPhamSummary ()
    {
        List <InpPhamApplyDetailSummaryModel> models = m_phamDisenpseCollectGrid.getGrid ().getStore ().getModels ();
        if (models.isEmpty ())
        {
            return;
        }

        s_applyDetailRpc.getOffsetPhamSummaryList (models, new AsyncCallback <List <InpPhamApplyDetailModel>> ()
        {

            @Override
            public void onFailure (Throwable caught)
            {
                MessageBox.alert (CodeConstants.PROMPT, caught.getLocalizedMessage (), null);
            }

            @Override
            public void onSuccess (List <InpPhamApplyDetailModel> result)
            {
                addOffsetAjdustData (result, m_phamDisenpseCollectGrid.getGrid ().getStore ().getModels ());
            }
        });
    }

    /**
     * 将本次请领药品数据和可冲抵的药品信息进行对照后填入Grid中
     */
    private void addOffsetAjdustData (List <InpPhamApplyDetailModel> applyPhams,
                                      List <InpPhamApplyDetailSummaryModel> applySummarys)
    {
        ArrayList <InpPhamApplyDetailSummaryModel> models = new ArrayList <InpPhamApplyDetailSummaryModel> ();
        Map <String, InpPhamApplyDetailSummaryModel> map = convertSummaryListToMap (applySummarys);
        for (InpPhamApplyDetailModel model : applyPhams)
        {
            if (map.containsKey (model.getPhamStdCode ()))
            {
                models.add (map.get (model.getPhamStdCode ()));
            }
        }

        m_currentApplyGrid.getGrid ().getStore ().removeAll ();
        m_currentApplyGrid.getGrid ().getStore ().add (models);
        m_offsetGrid.getGrid ().getStore ().removeAll ();
        m_offsetGrid.getGrid ().getStore ().add (applyPhams);
    }

    /**
     * 将汇总列表转换成map
     * 
     * @param applySummarys
     * @return
     */
    private Map <String, InpPhamApplyDetailSummaryModel> convertSummaryListToMap (List <InpPhamApplyDetailSummaryModel> applySummarys)
    {
        Map <String, InpPhamApplyDetailSummaryModel> map = new HashMap <String, InpPhamApplyDetailSummaryModel> ();
        for (InpPhamApplyDetailSummaryModel model : applySummarys)
        {
            map.put (model.getPhamStdCode (), model);
        }
        return map;
    }

    private void cancleData ()
    {
        InpPhamApplyDetailModel model = m_phamDispenseNurseUnitInfoGrid.getGrid ().getSelectionModel ()
                                                                       .getSelectedItem ();
        s_dipenseDetailRpc.cancelApplyMaster (model.getApplyNo (), model.getNurseUnit (), new AsyncCallback <Void> ()
        {

            @Override
            public void onSuccess (Void result)
            {
                clearData ();
                Info.display ("提示", "作废成功");
                initData ();

            }

            @Override
            public void onFailure (Throwable caught)
            {
                clearData ();
                ClientUtils.alertMessageBox (caught.getLocalizedMessage (), null);

            }
        });
    }
    private boolean veryParams ()
    {
        if (m_phamApplyCancelConditionForm.getBeginDate ().getValue ()== null)
        {
            ClientUtils.alertMessageBox ("请选择开始时间", m_phamApplyCancelConditionForm.getBeginDate ());
            return false;
        }
        if (m_phamApplyCancelConditionForm.getEndDate ().getValue () == null)
        {
            ClientUtils.alertMessageBox ("请选择结束时间", m_phamApplyCancelConditionForm.getEndDate ());
            return false;
        }
        if(m_phamApplyCancelConditionForm.getBeginDate ().getValue ().after (m_phamApplyCancelConditionForm.getEndDate ().getValue ())){
            ClientUtils.alertMessageBox ("开始时间大于结束时间", m_phamApplyCancelConditionForm.getBeginDate ());
            return false;
        }
        return true;
    }
    /** 公司版权信息. */
    public static final String copyright = "Copyright 2014, TH Supcom Corporation";

    /** 提交路径. */
    public static final String SCC_BRANCH = "$URL$";

    /** 提交日期. */
    public static final String SCC_LAST_MODIFICATION_DATE = "$Date$";

    /** 最终修改人员. */
    public static final String SCC_LAST_MODIFIER_NAME = "$Author$";

    /** 最终版本号. */
    public static final String SCC_REVISION = "$Revision$";
}